package com.yazi.mxz.common.service.impl;

import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;

import javax.annotation.Resource;



import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import com.myframework.smhj.common.exception.MyEntityNotExistsException;
import com.myframework.smhj.common.exception.MyException;
import com.myframework.smhj.common.exception.MyIllegalArgumentException;
import com.myframework.smhj.common.exception.MyNoPermissionException;
import com.myframework.smhj.hibernate.dao.BasicService;
import com.myframework.smhj.hibernate.dao.Dao;
import com.yazi.mxz.common.MyUtil;
import com.yazi.mxz.common.db.dao.LocalSaleGoodsDao;
import com.yazi.mxz.common.db.dao.LocalSaleDao;
import com.yazi.mxz.common.db.dao.StoreDao;
import com.yazi.mxz.common.db.dao.StoreGoodsDao;
import com.yazi.mxz.common.entity.ValueFactory;
import com.yazi.mxz.common.entity.beans.LocalSaleGoods;
import com.yazi.mxz.common.entity.beans.LocalSale;
import com.yazi.mxz.common.entity.beans.Store;
import com.yazi.mxz.common.entity.beans.StoreGoods;
import com.yazi.mxz.common.service.LocalSaleService;

@Service("localSaleService")
public class LocalSaleServiceImpl extends BasicService<LocalSale> implements LocalSaleService {
	private static Logger log = LoggerFactory.getLogger(LocalSaleServiceImpl.class);
	
	@Resource
	LocalSaleDao localSaleDao;
	@Resource
	LocalSaleGoodsDao localSaleGoodsDao;
	@Resource
	StoreGoodsDao storeGoodsDao;
	@Resource
	StoreDao storeDao;
	
	@Override
	protected Dao<LocalSale> getDao() {
		return localSaleDao;
	}
	
	@Override
	public LocalSale add(LocalSale sale) throws MyException {
		log.debug("add：");
		
		// 数量检查
		Store store = sale.getStore();
		if (store.getPutupRemain() <= 0) {
			throw new MyNoPermissionException("已有过多未完成订单");
		}
		store.setPutupRemain(store.getPutupRemain() - 1);
		storeDao.merge(store);
		
		ValueFactory.validate(sale);
		sale.setSerialCode(MyUtil.makeSerialCode(store.getStoreId()));
		sale.setSaleId(null);
		return localSaleDao.persist(sale);
	}

	@Override
	public void editByStore(Store store, LocalSale sale, List<LocalSaleGoods> ogs) throws MyException {
		log.debug("updateByStore：storeId={},saleId={},size={}",
				new Object[]{store.getStoreId(), sale.getSaleId(), ogs.size()});
		
		Long saleId = sale.getSaleId();
		if (null == saleId || null == ogs || ogs.size() == 0) {
			throw new MyIllegalArgumentException();
		}
		
		// 检查出售单与当前店铺的关系
		LocalSale destSale = localSaleDao.get(saleId);
		if (null == destSale) {
			throw new MyEntityNotExistsException();
		} else if (!destSale.getStore().equals(store)) {
			throw new MyNoPermissionException();
		}
		
		// 原有物品
		Set<LocalSaleGoods> exsitsOgs = destSale.getLocalSaleGoodses();
		// 此次更新到的原有物品
		Set<LocalSaleGoods> updatedOgs = new HashSet<LocalSaleGoods>(); 
		
		for (LocalSaleGoods og : ogs) {
			if (null == og) {
				throw new MyIllegalArgumentException();
			}
			
			/* 检查关联的商品 */
			StoreGoods sg = og.getStoreGoods();
			Long sgId = null;
			if (null == sg || null == (sgId = sg.getStoreGoodsId())) {
				throw new MyIllegalArgumentException();
			}
			sg = storeGoodsDao.get(sgId);
			if (null == sg) {
				throw new MyEntityNotExistsException();
			} else if (!sg.getStore().equals(store)) {
				throw new MyNoPermissionException();
			}
			
			/* 添加新的物品或者更新已有的物品 */
			
			Long ogId = og.getSaleGoodsId();
			if (null == ogId) {
				og.setLocalSale(destSale);
				localSaleGoodsDao.persist(og);
			} else {
				// 检查已有物品与当前出售单的关系
				LocalSaleGoods destOg = localSaleGoodsDao.get(ogId);
				if (null == destOg) {
					throw new MyEntityNotExistsException();
				} else if (!destOg.getLocalSale().equals(destSale)) {
					throw new MyNoPermissionException();
				}
				
				og.setLocalSale(null);
				og.setSaleGoodsId(null);
				
				ValueFactory.combine(og, destOg);
				localSaleGoodsDao.merge(destOg);
				
				updatedOgs.add(destOg);
			}
		}
		
		// 删除此次没有更新到的原有物品
		exsitsOgs.removeAll(updatedOgs);
		Iterator<LocalSaleGoods> its = exsitsOgs.iterator();
		while (its.hasNext()) {
			localSaleGoodsDao.delete(its.next());
		}
		
		// ...
		// offlineSaleDao.merge(destSale);
	}

	@Override
	public void removeByStore(Store store, long saleId) {
		log.debug("removeByStore：storeId={},saleId={}", store.getStoreId(), saleId);
		
		LocalSale sale = localSaleDao.get(saleId);
		if (null == sale || !sale.getStore().equals(store)) {
			return;
		} 
		
		// TODO 系统本身有限制每个店铺允许挂起单数（比较少），所以允许通过此遍历方式删除售单物品
		Iterator<LocalSaleGoods> it = sale.getLocalSaleGoodses().iterator();
		while (it.hasNext()) {
			localSaleGoodsDao.delete(it.next());
		}
		localSaleDao.delete(sale);
		
		// 可挂订单数
		store.setPutupRemain(store.getPutupRemain() + 1);
		storeDao.merge(store);
	}

}
